package com.kk.miaosha.securityEntity;

import cn.hutool.http.HttpStatus;
import com.kk.miaosha.entity.User;
import com.kk.miaosha.exception.CustomException;
import com.kk.miaosha.mapper.UserMapper;
import com.kk.miaosha.service.UserService;
import com.kk.miaosha.utils.RedisKeyUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author : K k
 * @date : 16:25 2020/10/21
 */
@Component
public class UserDetailService implements UserDetailsService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private UserService userService;
    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("我进来了...loadUserByUsername");
        UserDetail userDetail = getCache(username);
        if (userDetail==null){
            //若缓存中不存在用户信息或对应的权限信息
            userDetail=new UserDetail();
            User user = userService.findOne(username);
            if (user==null){
                throw new CustomException(HttpStatus.HTTP_BAD_REQUEST,"账号信息有误！");
            }
            userDetail.setUser(user);
            List<String> authorties=userMapper.findUserMenuList(user.getId());
            if (authorties != null) {
                userDetail.setSourceList(authorties);
            }
            //放入缓存
            setCache(user, authorties);
        }
        userDetail.setAuthorities(
                AuthorityUtils.commaSeparatedStringToAuthorityList(
                        String.join(",", userDetail.getSourceList())
                )
        );
        return userDetail;
    }

    //读取缓存
    private UserDetail getCache(String username) {
        String userKey = RedisKeyUtil.getUserKey(username);
        User user= (User) redisTemplate.opsForValue().get(userKey);
        if (user!=null){
            String userMenuKey = RedisKeyUtil.getUserMenuKey(username);
            //获取对应用户的权限
            List<String> resourceList= (List<String>) redisTemplate.opsForValue().get(userMenuKey);
            if (resourceList!=null && resourceList.size()>0){
                UserDetail userDetail=new UserDetail();
                userDetail.setUser(user);
                userDetail.setSourceList(resourceList);
                return userDetail;
            }
        }
        return null;
    }

    //写入缓存
    private void setCache(User user, List<String> authorties) {
        String userKey = RedisKeyUtil.getUserKey(user.getUserName());
        redisTemplate.opsForValue().set(userKey,user, 24,TimeUnit.HOURS);//缓存1个小时
        String userMenuKey = RedisKeyUtil.getUserMenuKey(user.getUserName());
        redisTemplate.opsForValue().set(userMenuKey,authorties,24,TimeUnit.HOURS);
    }
}
